﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Babelfish.Node
{
    /// <summary>
    /// 
    /// </summary>
    public class NodeCollection : IEnumerable<INode>
    {
        private List<INode> _list;

        /// <summary>
        /// 
        /// </summary>
        public delegate void CollectionUpdatedHandler(object sender, EventArgs args);

        /// <summary>
        /// Occurs when [collection updated].
        /// </summary>
        public event CollectionUpdatedHandler CollectionUpdated;


        /// <summary>
        /// Initializes a new instance of the <see cref="NodeCollection"/> class.
        /// </summary>
        /// <param name="nodes">The nodes.</param>
        public NodeCollection(IEnumerable<INode> nodes)
        {
            _list = new List<INode>(nodes);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="NodeCollection"/> class.
        /// </summary>
        public NodeCollection()
        {
            _list = new List<INode>();
        }


        /// <summary>
        /// Adds the specified attribute.
        /// </summary>
        /// <param name="attribute">The attribute.</param>
        public void Add(INode node)
        {
            //attribute.ParentCollection = this;

            _list.Add(node);
            if (CollectionUpdated != null)
                CollectionUpdated(this, new EventArgs());
        }

        /// <summary>
        /// Adds the range.
        /// </summary>
        /// <param name="list">The list.</param>
        public void AddRange(IEnumerable<INode> nodes)
        {
            foreach (var node in nodes)
                node.ParentCollection = this;

            _list.AddRange(nodes);

            if (CollectionUpdated != null)
                CollectionUpdated(this, new EventArgs());
        }


        /// <summary>
        /// Removes the specified node.
        /// </summary>
        /// <param name="node">The node.</param>
        public void Remove(INode node)
        {
            _list.Remove(node);

            if (CollectionUpdated != null)
                CollectionUpdated(this, new EventArgs());
        }


        /// <summary>
        /// Removes the specified nodes.
        /// </summary>
        /// <param name="nodes">The nodes.</param>
        public void Remove(IEnumerable<INode> nodes)
        {
            foreach (var node in nodes)
                _list.Remove(node);

            if (CollectionUpdated != null)
                CollectionUpdated(this, new EventArgs());
        }

        /// <summary>
        /// Gets the <see cref="Babelfish.INode"/> with the specified node name.
        /// </summary>
        /// <value></value>
        public INode this[string nodeName]
        {
            get
            {
                return this.Where(node => node.Name == nodeName).FirstOrDefault() ?? new EmptyNode();
            }
        }

        /// <summary>
        /// Gets the <see cref="Babelfish.INode"/> at the specified index.
        /// </summary>
        /// <value></value>
        public INode this[int index]
        {
            get
            {
                return this._list[index];
            }
        }

        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
        /// </returns>
        public IEnumerator<INode> GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}
